#pragma once 

#include "CoreClasses\Camera\Camera.h"
#include "World\View Plane Details\ViewPlane.h"
#include "CoreClasses\RGBObject\RGBColor.h"
#include "Tracer\Tracer.h"
#include "Scene\Scene.h"

namespace Engine
{
	class AbstractWorld
	{
	public:
		virtual void Build(void) = 0;
		virtual void Build(Camera* p_camera) = 0;
		virtual bool RenderScene() = 0;
		virtual void Shade() = 0;

		ViewPlane vp;
		RGBColor backgroundColor;
		Tracer* tracer_ptr;
		Pixel *buffer;
		Scene *currentScene;
		int sceneType;
		int eye;
		IrradianceCache* integrator;
		Camera* m_camera;
		int d;

		int m_currentY;
		Pixel* m_currentPixel;
		Logger m_logFile;
		//----------------------------------------------------------------------------------------------------------------
		//		 Method Name: CONSTRUCTOR
		//		Return Value: VOID
		//		  Parameters: VOID
		//			  Status: READY
		//----------------------------------------------------------------------------------------------------------------
		AbstractWorld(void) : tracer_ptr(NULL)
		{
			backgroundColor = RGBColor(0, 0, 0);
		}
		//----------------------------------------------------------------------------------------------------------------
		//		 Method Name: CONSTRUCTOR
		//		Return Value: VOID
		//		  Parameters: int Scene Type
		//			  Status: DEPECRATED
		//----------------------------------------------------------------------------------------------------------------
		AbstractWorld(int m_sceneType) : sceneType(m_sceneType)
		{
		}
		//----------------------------------------------------------------------------------------------------------------
		//		 Method Name: CONSTRUCTOR
		//		Return Value: VOID
		//		  Parameters: int Scene Type, int Width, int Height
		//			  Status: READY
		//----------------------------------------------------------------------------------------------------------------
		AbstractWorld(int m_sceneType, int m_width, int m_height) : sceneType(m_sceneType)
		{
			vp.hres = m_width;
			vp.vres = m_height;
			vp.s = 1;
		}
		//----------------------------------------------------------------------------------------------------------------
		//		 Method Name: CONSTRUCTOR
		//		Return Value: VOID
		//		  Parameters: int Scene Type, int width, int height, string Image path
		//			  Status: READY
		//----------------------------------------------------------------------------------------------------------------
		AbstractWorld(int m_sceneType, int m_width, int m_height, string p_ImagePath) : sceneType(m_sceneType)
		{
			vp.hres = m_width;
			vp.vres = m_height;
			vp.s = 1;
		}
		//----------------------------------------------------------------------------------------------------------------
		//		 Method Name: ClampToColor
		//		Return Value: RGBColor
		//		  Parameters: RGBColor
		//			  Status: READY
		//----------------------------------------------------------------------------------------------------------------
		RGBColor ClampToColor(RGBColor rawColor) const
		{
			RGBColor c(rawColor);

			if (rawColor.r > 1.0 || rawColor.g > 1.0 || rawColor.b > 1.0) {
				c.r = 1.0; c.g = 0.0; c.b = 0.0;
			}

			return (c);
		}
		//----------------------------------------------------------------------------------------------------------------
		//		 Method Name: CONSTRUCTOR
		//		Return Value: RGBColor
		//		  Parameters: RGBColor
		//			  Status: READY
		//----------------------------------------------------------------------------------------------------------------
		RGBColor MaxToOne(RGBColor c) const
		{
			float max_value = max(c.r, max(c.g, c.b));

			if (max_value > 1.0)
				return (c / max_value);
			else
				return (c);
		}
		//----------------------------------------------------------------------------------------------------------------
		//		 Method Name: GetBuffer
		//		Return Value: Pixel*
		//		  Parameters: VOID
		//			  Status: DEPCRATED
		//----------------------------------------------------------------------------------------------------------------
		Pixel* GetBuffer()
		{
			return buffer;
		}

	private:
		ShadeRec m_currentShadrec;

	private:
	};
}